﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.Transactions;
using Microsoft.ServiceModel.DomainServices.LinqToSql;
using Quizz.DataRepository.Models;

namespace Quizz.Service
{
    [EnableClientAccess()]
    public class QuizzDomainService<T> : LinqToSqlDomainService<T> where T : DataContext, new()
    {
        #region Fields

        private DataContext _dataContext;
        private const string ConnectionStringKey = "Development";

        #endregion

        #region Properties

        public string ConnectionString { get; set; }

        public new T DataContext
        {
            get { return (this._dataContext as T) ?? base.DataContext; }
            set { this._dataContext = value; }
        }

        #endregion

        #region Methods

        protected override T CreateDataContext()
        {
            var connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringKey];
            if(connectionString == null || string.IsNullOrEmpty(connectionString.ConnectionString))
                throw new InvalidOperationException(string.Format("Connection string '{0}' cant not found ! Please add it to config file...", ConnectionStringKey));
            this.ConnectionString = connectionString.ConnectionString;

            this.DataContext = new QuizzDataContext(this.ConnectionString) as T;
            return this.DataContext as T;
        }
        
        protected override bool ResolveConflicts(ChangeConflictCollection conflicts)
        {
            if(!base.ResolveConflicts(conflicts))
            {
                this.DataContext.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
                this.DataContext.SubmitChanges();
            }
            return this.DataContext.ChangeConflicts.Count == 0;
        }

        public void ExecuteCommand(string sql, params object[] parameters)
        {
            using(var transaction = new TransactionScope())
            {
                this.DataContext.ExecuteCommand(sql, parameters);
                transaction.Complete();
            }
        }

        public IEnumerable<TK> ExecuteQuery<TK>(string sql , params object[] parameters)
        {
            return this.DataContext.ExecuteQuery<TK>(sql, parameters);
        }

        public bool Haschange()
        {
            return this.DataContext.GetChangeSet().Deletes.Count > 0 ||
                   this.DataContext.GetChangeSet().Inserts.Count > 0 ||
                   this.DataContext.GetChangeSet().Updates.Count > 0;
        }

        #endregion
    }
}


